package com.cheetah.protocol.codec;

import com.cheetah.exceptions.CheetahException;
import com.cheetah.protocol.CheetahMessage;
import com.cheetah.protostuff.ProtostuffSerialization;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.MessageToByteEncoder;
import io.netty.util.ReferenceCountUtil;


/**
 * @Description:
 *   编码器
 *
 *   协议
 * |======================================================================================|
 * |    协议魔数  |  协议版本   |协议载体类型（对象）|    flag     |   bodyLen |     body        |
 * |    short    |  short    |     String     |    short    |    int    |     byte[]      |
 * |<--2 bytes-->|<-2 bytes->|<----4 bytes--->|<--2 bytes-->|<--4bytes->|<--- bodyLen---> |
 * |======================================================================================|
 */
public class CheetahEncoder extends MessageToByteEncoder<CheetahMessage> {


    @Override
    protected void encode(ChannelHandlerContext ctx, CheetahMessage cheetahMessage, ByteBuf out) throws Exception {

        ByteBuf buffer = ctx.alloc().buffer();
        try {
            buffer.writeShort(cheetahMessage.getMagic());
            buffer.writeShort(cheetahMessage.getVersion());
            buffer.writeBytes(cheetahMessage.getType().getBytes());
            buffer.writeShort(cheetahMessage.getFlag());
//            buffer.writeInt(cheetahMessage.getHeadLen());
            buffer.writeInt(cheetahMessage.getBodyLen());

//            if(cheetahMessage.getHeadLen() > 0){
//                buffer.writeBytes(ProtostuffSerialization.serialize(cheetahMessage.getHeader()));
//            }

            if (cheetahMessage.getBodyLen() > 0) {
                buffer.writeBytes(cheetahMessage.getData());
            }

            out.writeBytes(buffer);

        }catch (Throwable t){
            throw new CheetahException(t.getMessage(),t);
        }finally {
            ReferenceCountUtil.release(buffer);
        }
    }
}
